package org.neptune.service.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.neptune.api.response.SeckillResponse;
import org.neptune.common.constant.CharacterConstant;
import org.neptune.common.constant.NeptuneConstant;
import org.neptune.common.enums.SeckillStatus;
import org.neptune.service.config.NeptuneConfig;
import org.neptune.service.redis.RedisRepository;
import org.neptune.service.redis.RedissonUtil;
import org.neptune.service.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;

/**
 * @author lwl
 * @date 2019/8/6 17:26
 */
public class IpInterceptor implements HandlerInterceptor {

	private static final Logger logger = LoggerFactory.getLogger(IpInterceptor.class);

	/**
	 * ajax请求头部key
	 */
	public static final String X_REQUESTED_WITH = "X-Requested-With";

	/**
	 * ajax请求头部value
	 */
	public static final String XMLHTTPREQUEST = "XMLHttpRequest";

	@Autowired
	private RedisRepository redisRepository;

	@Autowired
	private NeptuneConfig neptuneConfig;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object handler) throws Exception {
		logger.info("into ip interceptor ");
		String ip = IpUtil.getIpAddr(request);
		if (StringUtils.isNotBlank(ip)){
			String cacheKey = RedissonUtil.getRedisKey(
					NeptuneConstant.REDIS_SECKILL_REQUEST_COUNT_IP,
					StringUtils.replace(ip, CharacterConstant.COLON_EN, CharacterConstant.HYPHEN));
			int accessTimes = redisRepository.incrementReturnint(cacheKey,
					neptuneConfig.ipCacheTime);
			if (accessTimes >= neptuneConfig.ipAccessTimesLimit){
				if (this.isAjaxRequest(request)){
					response.setContentType("text/plain; charset=utf-8");
					SeckillResponse seckillResponse = new SeckillResponse();
					seckillResponse.setMsg(SeckillStatus.ERROR.getMsg());
					seckillResponse.setCode(SeckillStatus.ERROR.getStatus());
					String respStr = JSON.toJSONString(seckillResponse);
					response.getWriter().write(respStr);
				}
				return false;
			}
		}
		return true;
	}

	private boolean isAjaxRequest(HttpServletRequest request) {
		String xRequestedWith = request.getHeader(X_REQUESTED_WITH);
		return (StringUtils.isNotBlank(xRequestedWith)
				&& XMLHTTPREQUEST.equals(xRequestedWith));
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
			Object handler, Exception ex) throws Exception {
	}
}
